<script lang="ts" setup>
  import { useI18n } from 'vue-i18n';
  import { ValidatedError } from '@arco-design/web-vue';
  import { useUserStore } from '@/store';
  import { PhoneLoginReq } from '@/api/auth';
  import { BehaviorCaptchaReq, getSmsCaptcha } from '@/api/common/captcha';

  const { proxy } = getCurrentInstance() as any;
  const { t } = useI18n();
  const router = useRouter();
  const userStore = useUserStore();
  const formRef = ref();
  const loading = ref(false);
  const captchaLoading = ref(false);
  const captchaDisable = ref(true);
  const captchaTime = ref(60);
  const captchaTimer = ref();
  const captchaType = ref('blockPuzzle');
  const captchaMode = ref('pop');
  const captchaBtnNameKey = ref('login.captcha.get');
  const captchaBtnName = computed(() => t(captchaBtnNameKey.value));
  const data = reactive({
    form: {
      phone: '',
      captcha: '',
    } as PhoneLoginReq,
    rules: {
      phone: [
        { required: true, message: t('login.phone.error.required.phone') },
        {
          match: /^1[3-9]\d{9}$/,
          message: t('login.phone.error.match.phone'),
        },
      ],
      captcha: [
        { required: true, message: t('login.phone.error.required.captcha') },
      ],
    },
  });
  const { form, rules } = toRefs(data);

  /**
   * 弹出行为验证码
   */
  const handleOpenBehaviorCaptcha = () => {
    if (captchaLoading.value) return;
    formRef.value.validateField('phone', (valid: any) => {
      if (!valid) {
        proxy.$refs.verifyRef.show();
      }
    });
  };

  /**
   * 重置验证码
   */
  const resetCaptcha = () => {
    window.clearInterval(captchaTimer.value);
    captchaTime.value = 60;
    captchaBtnNameKey.value = 'login.captcha.get';
    captchaDisable.value = false;
  };

  /**
   * 发送验证码
   */
  const handleSendCaptcha = (captchaParam: BehaviorCaptchaReq) => {
    if (captchaLoading.value) return;
    formRef.value.validateField('phone', (valid: any) => {
      if (!valid) {
        captchaLoading.value = true;
        captchaBtnNameKey.value = 'login.captcha.ing';
        getSmsCaptcha(form.value.phone, captchaParam)
          .then((res) => {
            captchaLoading.value = false;
            captchaDisable.value = true;
            captchaBtnNameKey.value = `${t(
              'login.captcha.get',
            )}(${(captchaTime.value -= 1)}s)`;
            captchaTimer.value = window.setInterval(() => {
              captchaTime.value -= 1;
              captchaBtnNameKey.value = `${t('login.captcha.get')}(${
                captchaTime.value
              }s)`;
              if (captchaTime.value <= 0) {
                resetCaptcha();
              }
            }, 1000);
            proxy.$message.success(res.msg);
          })
          .catch(() => {
            resetCaptcha();
            captchaLoading.value = false;
          });
      }
    });
  };

  /**
   * 登录
   *
   * @param errors 表单验证错误
   * @param values 表单数据
   */
  const handleLogin = ({
    errors,
    values,
  }: {
    errors: Record<string, ValidatedError> | undefined;
    values: Record<string, any>;
  }) => {
    if (loading.value) return;
    if (!errors) {
      loading.value = true;
      userStore
        .phoneLogin({
          phone: values.phone,
          captcha: values.captcha,
        })
        .then(() => {
          const { redirect, ...othersQuery } = router.currentRoute.value.query;
          router.push({
            name: (redirect as string) || 'Workplace',
            query: {
              ...othersQuery,
            },
          });
          proxy.$notification.success(t('login.success'));
        })
        .catch(() => {
          form.value.captcha = '';
        })
        .finally(() => {
          loading.value = false;
        });
    }
  };
</script>

<template>
  <a-form
    ref="formRef"
    :model="form"
    :rules="rules"
    layout="vertical"
    size="large"
    class="login-form"
    @submit="handleLogin"
  >
    <a-form-item field="phone" hide-label>
      <a-select :options="['+86']" style="flex: 1 1" default-value="+86" />
      <a-input
        v-model="form.phone"
        :placeholder="$t('login.phone.placeholder.phone')"
        :max-length="11"
        allow-clear
      />
    </a-form-item>
    <a-form-item field="captcha" hide-label>
      <a-input
        v-model="form.captcha"
        :placeholder="$t('login.phone.placeholder.captcha')"
        :max-length="4"
        allow-clear
        style="flex: 1 1"
      />
      <a-button
        class="captcha-btn"
        :loading="captchaLoading"
        :disabled="captchaDisable"
        @click="handleOpenBehaviorCaptcha"
      >
        {{ captchaBtnName }}
      </a-button>
    </a-form-item>
    <a-button
      class="btn"
      :loading="loading"
      type="primary"
      html-type="submit"
      :disabled="captchaDisable"
      >{{ $t('login.button') }}（演示不开放）
    </a-button>
  </a-form>
  <Verify
    ref="verifyRef"
    :mode="captchaMode"
    :captcha-type="captchaType"
    :img-size="{ width: '330px', height: '155px' }"
    @success="handleSendCaptcha"
  ></Verify>
</template>

<style lang="less" scoped>
  .login-form {
    box-sizing: border-box;
    padding: 0 5px;
    margin-top: 16px;
    .arco-input-wrapper,
    :deep(.arco-select-view-single) {
      background-color: #fff;
      border: 1px solid #c9cdd4;
      height: 40px;
      border-radius: 4px;
      font-size: 13px;
    }
    .arco-input-wrapper.arco-input-error {
      background-color: rgb(255, 236, 232);
      border-color: rgb(249, 137, 129);
    }
    .arco-input-wrapper :deep(.arco-input) {
      color: rgb(29, 33, 41);
    }

    .captcha-btn {
      height: 40px;
      margin-left: 12px;
      min-width: 98px;
      border-radius: 4px;
    }

    .arco-btn-secondary:not(.arco-btn-disabled) {
      background-color: #f6f8fa;
      border: 1px solid #dde2e9;
      color: #41464f;
    }
    .arco-btn-secondary.arco-btn-disabled,
    .arco-btn-secondary[type='submit'].arco-btn-disabled {
      color: #c9cdd4;
      background-color: rgb(247, 248, 250);
    }
    .arco-btn-secondary:not(.arco-btn-disabled):hover {
      background-color: transparent;
      border: 1px solid rgb(22, 93, 255);
    }

    .btn {
      border-radius: 4px;
      box-shadow:
        0 0 0 1px #05f,
        0 2px 1px rgba(0, 0, 0, 0.15);
      font-size: 14px;
      font-weight: 500;
      height: 40px;
      line-height: 22px;
      margin: 20px 0 12px;
      width: 100%;
    }

    .arco-btn-primary.arco-btn-disabled,
    .arco-btn-primary[type='submit'].arco-btn-disabled {
      color: #fff;
      background-color: rgb(201, 205, 212);
      box-shadow:
        0 0 0 1px rgb(201, 205, 212),
        0 2px 1px #00000026;
    }
  }
</style>
